home *** CD-ROM | disk | FTP | other *** search
- /*
- * undump new old <args>
- * undump the memory image of old to new
- * old is run with args, and when it exits, its memory image is
- * undump'ed into new.
- * Gcc probably required.
- *
- * ++jrb bammi@dsrgsun.ces.cwru.edu
- */
- #include <stdio.h>
- #include <basepage.h>
- #include <st-out.h>
- #include <osbind.h>
- #include <string.h>
-
- #define BSIZ 8192L
- char buf[BSIZ];
- char oldname[FILENAME_MAX], newname[FILENAME_MAX];
-
- static unsigned long getlong(FILE *f)
- {
- unsigned long l;
- if(fread(&l, sizeof l, 1, f) != 1)
- {
- fprintf(stderr,"%s: unexpected EOF\n", oldname);
- exit(92);
- }
- return l;
- }
-
- static void copy(FILE *, FILE *, unsigned long);
- static void makeenv(int, char **, char **);
-
- int main(int argc, char **argv, char **envp)
- {
- FILE *new, *old;
- FILE *fopen();
- struct aexec newhead, oldhead;
- BASEPAGE *bp;
- long l;
- unsigned long roffset, ul;
- char *patchloc;
- unsigned long getlong(FILE *);
-
- /* chk args */
- if(argc < 3)
- {
- fprintf(stderr,"usage: undump new old [args..]\n");
- exit(1);
- }
-
- /* open files */
- if((new = fopen(argv[1], "wb")) == NULL)
- {
- perror(argv[1]);
- exit(2);
- }
- strncpy(newname, argv[1], FILENAME_MAX);
- if((old = fopen(argv[2], "rb")) == NULL)
- {
- perror(argv[2]);
- exit(3);
- }
- strncpy(oldname, argv[2], FILENAME_MAX);
-
- /* read header from old */
- if(fread(&oldhead, sizeof oldhead, 1, old) != 1)
- {
- perror(oldname);
- exit(4);
- }
- if(A_BADMAG(oldhead)) /* check its magic # */
- {
- fprintf(stderr,"%s: bad magic number 0x%x\n", oldname,oldhead.a_magic);
- exit(5);
- }
- /* make up new head */
- newhead = oldhead;
- newhead.a_data = oldhead.a_data + oldhead.a_bss;
- newhead.a_bss = 0L;
-
- /* write new head */
- if(fwrite(&newhead, sizeof newhead, 1, new) != 1)
- {
- perror(newname);
- exit(6);
- }
-
- /* pick up args and make env */
- makeenv(argc, argv, envp);
- /* &buf[0] == command tail, &buf[130] == envp */
-
- /* load old into mem and grab basepage */
- if((l = Pexec(PE_LOAD, oldname, buf, &buf[130])) < 0)
- {
- fprintf(stderr,"%s: could'nt load\n", oldname);
- exit(7);
- }
- bp = (BASEPAGE *)l;
- roffset = (unsigned long)(bp->p_tbase); /* grab reloc offset */
- bzero(bp->p_bbase, bp->p_blen); /* not sure if this is needed */
-
- /* now do the just go */
- (void)Pexec(PE_GO, 0L, bp, 0L);
-
- /* un-relocate stuff in the text and data segments in core,
- and then dump it all into new */
- /* seek to reloc part of old */
- if(fseek(old, A_SYMOFF(oldhead) + oldhead.a_syms, SEEK_SET) < 0)
- {
- perror(oldname);
- exit(8);
- }
-
- /* step through relocs, reading relocs from old, and unrelocating */
- /* the corresponding items in core */
- ul = getlong(old); /* initial off from begining of text */
- patchloc = (char *)(roffset + ul);
- while(1)
- {
- *((unsigned long *)patchloc) -= roffset; /* un-reloc */
- more:
- if((ul = (unsigned long)getc(old)) == 0)
- break; /* all done */
- if(ul == 1)
- {
- patchloc += 254L;
- goto more;
- }
- else if(ul == 3)
- {
- fprintf(stderr,"WARNING: illegal reloc %ld (ignored)\n", ul);
- goto more;
- } /* note we let ul==2 pass thru */
- patchloc += ul;
- }
-
- /* dump text+data+bss from core into new */
- if(fwrite(bp->p_tbase, newhead.a_text + newhead.a_data, 1, new) != 1)
- {
- perror(newname);
- exit(11);
- }
- if(fseek(old, A_SYMOFF(oldhead), SEEK_SET) < 0)
- {
- perror(oldname);
- exit(12);
- }
-
- /* copy rest of old into new (ie. the symt if any and the reloc) */
- copy(old, new, 0x7fffffffL);
-
-
- fclose(new);
- fclose(old);
- return 0;
- }
-
- /*
- * copy from -> to upto count bytes or EOF
- */
- static void copy(FILE *from, FILE *to, unsigned long count)
- {
- register unsigned long n;
-
- while(count > 0)
- {
- n = (count > BSIZ) ? BSIZ : count;
- if((n = fread(buf, 1, n, from)) <= 0)
- return;
- if(fwrite(buf, 1, n, to) != n)
- {
- perror(newname);
- exit(13);
- }
- count -= n;
- }
- }
-
- extern char **environ;
-
- static void makeenv(int argc, char **argv, char **envp)
- {
- int i, count, l;
- char *p;
-
- bzero(buf, 128L);
- if(envp == NULL)
- envp = environ;
- p = &buf[130];
- if(envp)
- {
- for(; *envp; envp++)
- {
- strcpy(p, *envp);
- p += (strlen(*envp) + 1);
- }
- }
- strcpy(p, "ARGV=");
- p += (strlen(p) + 1);
- strcpy(p, argv[2]);
- p += (strlen(p) + 1);
- strcpy(buf, " ");
- for(count = 0, i = 3; i < argc; i++)
- {
- l = strlen(argv[i]);
- if( (count += l) < 127)
- {
- strcat(buf, argv[i]);
- if((i+1) < argc)
- {
- strcat(buf, " ");
- count++;
- }
- }
- strcpy(p, argv[i]);
- p += (l+1);
- }
- *p++ = '\0'; *p = '\0';
- buf[0] = strlen(&buf[1]);
- }
-